package com.swyc.osschat.Test.designMode.xiangYuan.run;

import com.swyc.osschat.Test.designMode.xiangYuan.base.ChessPieces;
import com.swyc.osschat.Test.designMode.xiangYuan.fac.PiecesFactory;

/**
 * @description Java 享元模式
 * 一、定义
 *  运用共享技术来有效地支持大量颗粒度对象的复用，它通过共享已存在的对象来大幅减少需要创建的对象数量，避免大量相似对象的开销，从而提高系统资源的利用率。
 *  享元模式中存在以下两种状态：
 *      内部状态：即不会随着环境的改变而改变的可共享部分。
 *      外部状态：指随环境改变而改变的不可以共享的部分，享元模式的实现要领就是区分应用中的这两种状态，并将外部状态外部化。
 *  主要角色：
 *      抽象享元角色：通常是一个接口或抽象类，在抽象享元类中声明了具体享元类公共的方法，这些方法可以向外界提供享元对象的内部数据（内部状态），同时也可以通过这些方法来设置外部数据（外部状态）。
 *      具体享元角色：它实现了抽象享元类，称为享元对象，在具体享元类中为内部状态提供了存储空间，通常我们可以结合单例模式来设计具体享元类，为每一个具体享元类提供唯一的享元对象。
 *      非享元角色：并不是所有的抽象享元类的子类都需要被共享，不能被共享的子类可设计为非共享具体享元类，当需要一个非共享具体享元类的对象时可以直接通过实例化创建。
 *      享元工厂角色：负责创建和管理享元角色，当客户对象请求一个享元对象时，享元工厂检查系统中是否存在符合要求的享元对象，如果存在则提供给客户，如果不存在则创建一个新的享元对象。
 * 二、代码实现
 *  举例：在五子棋中包含了多个“黑棋”和“白棋”，我们开发的过程中不能每创建一个黑白棋都要new一个对象，这样时非常浪费内存的，所以我们采用享元模式来减少对象创建的数量。
 *  上面代码我们通过享元工厂获取了三次黑棋，并打印了三个黑棋的hashcode，其中1,2; 3,4; 5,6;就是指的非享元角色，它不需要共享但由外部传入，而且三个黑棋的hashcode都是一致的，这就说明我们获取的三个黑棋 都是指向同一个对象。
 * 三、总结
 *  优点：极大减少内存中相似对象的数量，节约系统资源。
 *  缺点：为了使对象可以共享，所以需要将享元对象的部分状态外部化，使程序逻辑变复杂。
 *  使用场景：一个系统中有大量相同或相似的对象造成内存大量的浪费。
 * @Author: z156940l@outlook.com
 * @className Test
 * @Date: 2022/7/25 22:54
 */
public class Test {

    public static void main(String[] args) {
        ChessPieces piece = PiecesFactory.getInstance().getPieces("black");
        piece.DownPieces(1,2);

        ChessPieces piece2 = PiecesFactory.getInstance().getPieces("black");
        piece2.DownPieces(3,4);

        ChessPieces piece3 = PiecesFactory.getInstance().getPieces("black");
        piece3.DownPieces(5,6);

        System.out.println(piece.hashCode());
        System.out.println(piece2.hashCode());
        System.out.println(piece3.hashCode());
    }
}
